package dbutils

import (
	"errors"
	"strings"
	"sync"

	"gitee.com/haodreams/golib/memconf"
	"github.com/astaxie/beego/config"
	"github.com/jinzhu/gorm"
)

func init() {
	config.Register("table", &Conf{})
}

//需要读取配置的数据库
var confdb *gorm.DB

const SysAppConfFlag = "app_system_config"

//SetDatabase 设置配置数据库
func SetDatabase(db *gorm.DB, confs ...*AppConf) {
	confdb = db
	conf := new(AppConf)
	if !db.HasTable(conf) {
		db.CreateTable(conf)

	}

	count := 0
	err := db.Model(conf).Where("parent=?", SysAppConfFlag).Count(&count).Error
	if err != nil {
		return
	}
	if count == 0 {
		//初始化默认配置
		conf.Parent = SysAppConfFlag
		conf.Desc = "程序日志级别"
		conf.Name = "程序日志级别"
		conf.Key = "app_log_level"
		conf.Value = "info"
		conf.Type = "select"
		conf.Data = "debug|info|warn|error"
		db.Create(conf)
		for _, f := range confs {
			if f.Parent == "" {
				f.Parent = SysAppConfFlag
			}
			if f.Key != "" {
				db.Create(f)
			}
		}
	}
}

//Conf 读取配置文件
type Conf struct {
	memconf.Conf
	name string
}

//SaveConfigFile Save config
func (conf *Conf) SaveConfigFile(filename string) error {
	if confdb == nil {
		return errors.New("No database for config")
	}
	conf.Lock.Lock()
	defer conf.Lock.Unlock()

	confdb.Begin()
	for key, value := range conf.M {
		record := &AppConf{Value: value}
		if conf.name != "" {
			newdb := confdb.Model(record).Where("key = ? and parent = ?", key, conf.name).Update(record)
			if newdb.Error == nil && newdb.RowsAffected == 0 {
				confdb.Create(record)
			}
		} else {
			newdb := confdb.Model(record).Where("key = ? ", key).Update(record)
			if newdb.Error == nil && newdb.RowsAffected == 0 {
				confdb.Create(record)
			}
		}
	}
	confdb.Commit()
	return nil
}

//Parse 从关系库表中读取配置
func (conf *Conf) Parse(key string) (c config.Configer, err error) {
	if conf.Lock == nil {
		conf.Lock = new(sync.RWMutex)
	}
	if conf.M == nil {
		conf.M = map[string]string{}
	}
	conf.name = key
	conf.Lock.Lock()
	defer conf.Lock.Unlock()
	var rows []*AppConf

	rows, err = Find(conf.name)
	if err != nil {
		return
	}
	for _, row := range rows {
		key := row.Key
		value := row.Value
		key = strings.TrimSpace(key)
		value = strings.TrimSpace(value)
		conf.M[key] = value
	}
	c = conf
	return
}
